/*
 *    Copyright © OpenAtom Foundation.
 *
 *    Licensed under the Apache License, Version 2.0 (the "License");
 *    you may not use this file except in compliance with the License.
 *    You may obtain a copy of the License at
 *
 *         http://www.apache.org/licenses/LICENSE-2.0
 *
 *    Unless required by applicable law or agreed to in writing, software
 *    distributed under the License is distributed on an "AS IS" BASIS,
 *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *    See the License for the specific language governing permissions and
 *    limitations under the License.
 */

package com.inspur.edp.bef.core.be.builtinimpls;

import com.inspur.edp.bef.core.be.BEManager;
import com.inspur.edp.bef.core.determination.builtinimpls.BefB4QueryDtmAssembler;
import com.inspur.edp.bef.spi.entity.AbstractBizEntityDeSerializer;
import com.inspur.edp.bef.spi.entity.AbstractBizEntitySerializer;
import com.inspur.edp.bef.spi.entity.BefChangeDeserConvertor;
import com.inspur.edp.bef.spi.entity.BefChangeSerConvertor;
import com.inspur.edp.bef.spi.entity.BefEntityDeserConvertor;
import com.inspur.edp.bef.spi.entity.BefEntitySerConvertor;
import com.inspur.edp.cef.entity.UQConstraintConfig;
import com.inspur.edp.cef.spi.determination.IDetermination;
import com.inspur.edp.cef.spi.determination.IEntityRTDtmAssembler;
import com.inspur.edp.cef.spi.entity.resourceInfo.ModelResInfo;
import com.inspur.edp.cef.spi.entity.resourceInfo.builinImpls.CefEntityResInfoImpl;
import com.inspur.edp.cef.spi.entity.resourceInfo.builinImpls.CefModelResInfoImpl;
import com.inspur.edp.cef.spi.jsonser.abstractcefchange.AbstractCefChangeJsonDeserializer;
import com.inspur.edp.cef.spi.jsonser.abstractcefchange.AbstractCefChangeSerializer;
import lombok.SneakyThrows;

import java.util.ArrayList;
import java.util.HashMap;

public abstract class BefBuiltInManager extends BEManager {

  protected abstract BefManagerCacheInfo getManagerCacheInfo();

  @Override
  protected final ModelResInfo innerGetModelInfo() {
    if(getManagerCacheInfo().getModelResInfo()!=null)
      return getManagerCacheInfo().getModelResInfo();
    ModelResInfo modelResInfo=getModelInfo();
    getManagerCacheInfo().setModelResInfo(modelResInfo);
    return modelResInfo;
  }

  @Override
  public final ModelResInfo getModelInfo() {
    return getCefModelResourceInfo();
  }

  public abstract CefModelResInfoImpl getCefModelResourceInfo();

  @Override
  public final IEntityRTDtmAssembler getBeforeQueryDtmAssembler() {
    if(getManagerCacheInfo().getB4QueryDtmAssembler()!=null)
      return getManagerCacheInfo().getB4QueryDtmAssembler();
    IEntityRTDtmAssembler assembler=super.getBeforeQueryDtmAssembler();
    addBuiltInBeforeQueryDtms((BefB4QueryDtmAssembler)assembler);
    getManagerCacheInfo().setB4QueryDtmAssembler(assembler);
    return assembler;
  }

  private void addBuiltInBeforeQueryDtms(BefB4QueryDtmAssembler befB4QueryDtmAssembler) {
    addSecretLevelDtm(befB4QueryDtmAssembler);
  }

  @SneakyThrows
  private void addSecretLevelDtm(BefB4QueryDtmAssembler befB4QueryDtmAssembler) {
    Class c=Class.forName("com.inspur.edp.bef.builtincomponents.SecretLevel.SecurityLevelB4QueryDtmAdaptor");
    befB4QueryDtmAssembler.addDetermination((IDetermination) c.getConstructor().newInstance());
  }

  @Override
  public IEntityRTDtmAssembler getBeforeRetrieveDtmAssembler() {
    if(getManagerCacheInfo().getB4RetrieveDtmAssembler()!=null)
      return getManagerCacheInfo().getB4RetrieveDtmAssembler();
    IEntityRTDtmAssembler assembler=super.getBeforeRetrieveDtmAssembler();
    getManagerCacheInfo().setB4RetrieveDtmAssembler(assembler);
    return assembler;
  }

  //todo:从resourceInfo里获取
  @Override
  public HashMap<String, ArrayList<UQConstraintConfig>> getConstraintInfo() {
    return super.getConstraintInfo();
  }

  @Override
  public Object createPropertyDefaultValue(String nodeCode, String propertyName) {
    return ( (CefEntityResInfoImpl)getCefModelResourceInfo().getEntityResInfos().get(nodeCode.toLowerCase()))
        .getEntityTypeInfo().getPropertyInfo(propertyName).createPropertyDataValue();
  }

  @Override
  public AbstractBizEntityDeSerializer getDataDeserizlier() {
    return new BefEntityDeserConvertor(getCefModelResourceInfo().getRootNodeCode(), true, getBEInfo().getBEType(),
        (CefEntityResInfoImpl) getCefModelResourceInfo().getCustomResource(getCefModelResourceInfo().getRootNodeCode()));
  }

  @Override
  public AbstractBizEntitySerializer getDataSerialize() {
    return new BefEntitySerConvertor(getCefModelResourceInfo().getRootNodeCode(), true, getBEInfo().getBEType(),
        (CefEntityResInfoImpl) getCefModelResourceInfo().getCustomResource(getCefModelResourceInfo().getRootNodeCode()));
  }

  @Override
  protected AbstractCefChangeSerializer getChangeSerializer() {
    return new BefChangeSerConvertor(getCefModelResourceInfo().getRootNodeCode(), true, getBEInfo().getBEType(),
        (CefEntityResInfoImpl) getCefModelResourceInfo().getCustomResource(getCefModelResourceInfo().getRootNodeCode()));
  }

  @Override
  protected AbstractCefChangeJsonDeserializer getChangeDeserializer() {
    return new BefChangeDeserConvertor(getCefModelResourceInfo().getRootNodeCode(), true, getBEInfo().getBEType(),
        (CefEntityResInfoImpl) getCefModelResourceInfo().getCustomResource(getCefModelResourceInfo().getRootNodeCode()));
  }
}
